<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>JavaKeeper</title>
    <meta name="generator" content="VuePress 1.5.4">
    <link rel="icon" href="/icon.svg">
    <script>
        var _hmt = _hmt || [];
        (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?a949a9b30eb86ac0159e735ff8670c03";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
            // 引入谷歌,不需要可删除这段
            var hm1 = document.createElement("script");
            hm1.src = "https://www.googletagmanager.com/gtag/js?id=UA-169923503-1";
            var s1 = document.getElementsByTagName("script")[0]; 
            s1.parentNode.insertBefore(hm1, s1);
        })();
        // 谷歌加载,不需要可删除
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'UA-169923503-1');
    </script>
    <meta name="description" content="">
    <meta name="keywords" content="JavaKeeper,Java,Java开发,算法,blog">
    <link rel="preload" href="/assets/css/0.styles.91f57736.css" as="style"><link rel="preload" href="/assets/js/app.447d4224.js" as="script"><link rel="preload" href="/assets/js/3.9d76740c.js" as="script"><link rel="preload" href="/assets/js/1.c4fd7d2e.js" as="script"><link rel="preload" href="/assets/js/4.564edb9d.js" as="script"><link rel="prefetch" href="/assets/js/10.8cf3be2c.js"><link rel="prefetch" href="/assets/js/100.74f35ab8.js"><link rel="prefetch" href="/assets/js/101.7a062346.js"><link rel="prefetch" href="/assets/js/102.c9485235.js"><link rel="prefetch" href="/assets/js/103.d88a3805.js"><link rel="prefetch" href="/assets/js/104.6e034144.js"><link rel="prefetch" href="/assets/js/105.d22f7450.js"><link rel="prefetch" href="/assets/js/106.a6cb54b0.js"><link rel="prefetch" href="/assets/js/107.7b65e72b.js"><link rel="prefetch" href="/assets/js/108.eb5804bb.js"><link rel="prefetch" href="/assets/js/109.05f775e5.js"><link rel="prefetch" href="/assets/js/11.c54ae13c.js"><link rel="prefetch" href="/assets/js/110.51d3d641.js"><link rel="prefetch" href="/assets/js/111.022b64a7.js"><link rel="prefetch" href="/assets/js/112.da8afd52.js"><link rel="prefetch" href="/assets/js/113.05a17b18.js"><link rel="prefetch" href="/assets/js/114.8960d913.js"><link rel="prefetch" href="/assets/js/115.67919f68.js"><link rel="prefetch" href="/assets/js/116.62b0cd71.js"><link rel="prefetch" href="/assets/js/117.ebac3eff.js"><link rel="prefetch" href="/assets/js/118.ecd629bd.js"><link rel="prefetch" href="/assets/js/119.a09a0897.js"><link rel="prefetch" href="/assets/js/12.60aa3b24.js"><link rel="prefetch" href="/assets/js/120.bf639d3d.js"><link rel="prefetch" href="/assets/js/121.b89d0c8e.js"><link rel="prefetch" href="/assets/js/122.1a75ff83.js"><link rel="prefetch" href="/assets/js/123.d2127132.js"><link rel="prefetch" href="/assets/js/124.2caff9e0.js"><link rel="prefetch" href="/assets/js/125.9b9f966a.js"><link rel="prefetch" href="/assets/js/126.58cdfb3d.js"><link rel="prefetch" href="/assets/js/127.8ef09c53.js"><link rel="prefetch" href="/assets/js/128.efdc2ae4.js"><link rel="prefetch" href="/assets/js/129.e35cbc57.js"><link rel="prefetch" href="/assets/js/13.125c13a0.js"><link rel="prefetch" href="/assets/js/130.f01a55e3.js"><link rel="prefetch" href="/assets/js/131.65205f4a.js"><link rel="prefetch" href="/assets/js/132.f42c5a0a.js"><link rel="prefetch" href="/assets/js/133.9ba468b3.js"><link rel="prefetch" href="/assets/js/134.7b597ba9.js"><link rel="prefetch" href="/assets/js/135.fb828b9a.js"><link rel="prefetch" href="/assets/js/136.3887532f.js"><link rel="prefetch" href="/assets/js/137.549bae01.js"><link rel="prefetch" href="/assets/js/138.db8d423d.js"><link rel="prefetch" href="/assets/js/139.dbaf2267.js"><link rel="prefetch" href="/assets/js/14.bd1d0b0d.js"><link rel="prefetch" href="/assets/js/140.6cb65fdc.js"><link rel="prefetch" href="/assets/js/141.9bd6cc4b.js"><link rel="prefetch" href="/assets/js/142.552db5ed.js"><link rel="prefetch" href="/assets/js/143.2c9f2bf4.js"><link rel="prefetch" href="/assets/js/144.fba98a15.js"><link rel="prefetch" href="/assets/js/145.c42f3a21.js"><link rel="prefetch" href="/assets/js/146.596d4d33.js"><link rel="prefetch" href="/assets/js/147.c48ae5c1.js"><link rel="prefetch" href="/assets/js/148.71064871.js"><link rel="prefetch" href="/assets/js/149.16582d21.js"><link rel="prefetch" href="/assets/js/15.f247873b.js"><link rel="prefetch" href="/assets/js/150.ead09aca.js"><link rel="prefetch" href="/assets/js/151.971fdf4b.js"><link rel="prefetch" href="/assets/js/152.369c9362.js"><link rel="prefetch" href="/assets/js/153.371edd15.js"><link rel="prefetch" href="/assets/js/154.e090b491.js"><link rel="prefetch" href="/assets/js/155.c68bf602.js"><link rel="prefetch" href="/assets/js/156.304aea8d.js"><link rel="prefetch" href="/assets/js/157.83beef7f.js"><link rel="prefetch" href="/assets/js/158.bb1794b0.js"><link rel="prefetch" href="/assets/js/159.2d54e792.js"><link rel="prefetch" href="/assets/js/16.04336c71.js"><link rel="prefetch" href="/assets/js/160.99d56586.js"><link rel="prefetch" href="/assets/js/161.edf660aa.js"><link rel="prefetch" href="/assets/js/162.0b84606e.js"><link rel="prefetch" href="/assets/js/163.b59e0d60.js"><link rel="prefetch" href="/assets/js/164.d9eb8228.js"><link rel="prefetch" href="/assets/js/165.ca624c79.js"><link rel="prefetch" href="/assets/js/166.025b2ba1.js"><link rel="prefetch" href="/assets/js/167.abc982cc.js"><link rel="prefetch" href="/assets/js/168.27ca13dc.js"><link rel="prefetch" href="/assets/js/169.41e753a2.js"><link rel="prefetch" href="/assets/js/17.43b3c1c8.js"><link rel="prefetch" href="/assets/js/170.626319e1.js"><link rel="prefetch" href="/assets/js/171.a221dddf.js"><link rel="prefetch" href="/assets/js/172.464b2361.js"><link rel="prefetch" href="/assets/js/173.96a3afee.js"><link rel="prefetch" href="/assets/js/174.116607c2.js"><link rel="prefetch" href="/assets/js/175.ea3e8659.js"><link rel="prefetch" href="/assets/js/176.7d7b8afc.js"><link rel="prefetch" href="/assets/js/177.a6e00aa0.js"><link rel="prefetch" href="/assets/js/178.1f93afaf.js"><link rel="prefetch" href="/assets/js/179.3aa00dcd.js"><link rel="prefetch" href="/assets/js/18.d81b44d5.js"><link rel="prefetch" href="/assets/js/180.f8b2b75a.js"><link rel="prefetch" href="/assets/js/181.8e11258a.js"><link rel="prefetch" href="/assets/js/182.22243941.js"><link rel="prefetch" href="/assets/js/183.d051fdf6.js"><link rel="prefetch" href="/assets/js/184.a994075e.js"><link rel="prefetch" href="/assets/js/185.776c7e16.js"><link rel="prefetch" href="/assets/js/186.f1887955.js"><link rel="prefetch" href="/assets/js/187.da0d3626.js"><link rel="prefetch" href="/assets/js/188.8dfc358f.js"><link rel="prefetch" href="/assets/js/189.dcac5a59.js"><link rel="prefetch" href="/assets/js/19.1b3d66e1.js"><link rel="prefetch" href="/assets/js/190.c7e413d0.js"><link rel="prefetch" href="/assets/js/191.d9806121.js"><link rel="prefetch" href="/assets/js/192.869791da.js"><link rel="prefetch" href="/assets/js/193.2d74c4c8.js"><link rel="prefetch" href="/assets/js/194.c73a1909.js"><link rel="prefetch" href="/assets/js/195.e8c74834.js"><link rel="prefetch" href="/assets/js/20.bd5949ec.js"><link rel="prefetch" href="/assets/js/21.3fcf98cf.js"><link rel="prefetch" href="/assets/js/22.2fa1e2e8.js"><link rel="prefetch" href="/assets/js/23.1ae64bb4.js"><link rel="prefetch" href="/assets/js/24.7bdf7387.js"><link rel="prefetch" href="/assets/js/25.392c436e.js"><link rel="prefetch" href="/assets/js/26.58acbd4b.js"><link rel="prefetch" href="/assets/js/27.c725bdd5.js"><link rel="prefetch" href="/assets/js/28.6c9bda1e.js"><link rel="prefetch" href="/assets/js/29.e656b537.js"><link rel="prefetch" href="/assets/js/30.2c326fc7.js"><link rel="prefetch" href="/assets/js/31.e6c9fa30.js"><link rel="prefetch" href="/assets/js/32.c9c88437.js"><link rel="prefetch" href="/assets/js/33.0c53373c.js"><link rel="prefetch" href="/assets/js/34.9821e543.js"><link rel="prefetch" href="/assets/js/35.de8253eb.js"><link rel="prefetch" href="/assets/js/36.d182f929.js"><link rel="prefetch" href="/assets/js/37.9fa79014.js"><link rel="prefetch" href="/assets/js/38.9bebff76.js"><link rel="prefetch" href="/assets/js/39.19a3a2d4.js"><link rel="prefetch" href="/assets/js/40.cca6955f.js"><link rel="prefetch" href="/assets/js/41.854cd09a.js"><link rel="prefetch" href="/assets/js/42.ca7b612f.js"><link rel="prefetch" href="/assets/js/43.87027d58.js"><link rel="prefetch" href="/assets/js/44.8c2b4f4b.js"><link rel="prefetch" href="/assets/js/45.dffb4e08.js"><link rel="prefetch" href="/assets/js/46.f58049a5.js"><link rel="prefetch" href="/assets/js/47.6854070c.js"><link rel="prefetch" href="/assets/js/48.6cd9fa3d.js"><link rel="prefetch" href="/assets/js/49.e8861afa.js"><link rel="prefetch" href="/assets/js/5.5c31d62f.js"><link rel="prefetch" href="/assets/js/50.703bffab.js"><link rel="prefetch" href="/assets/js/51.6655c373.js"><link rel="prefetch" href="/assets/js/52.deb2eb09.js"><link rel="prefetch" href="/assets/js/53.6e0ed77d.js"><link rel="prefetch" href="/assets/js/54.b05c58ad.js"><link rel="prefetch" href="/assets/js/55.49c8164e.js"><link rel="prefetch" href="/assets/js/56.a5574e6b.js"><link rel="prefetch" href="/assets/js/57.58cb0de4.js"><link rel="prefetch" href="/assets/js/58.52345112.js"><link rel="prefetch" href="/assets/js/59.663ce78d.js"><link rel="prefetch" href="/assets/js/6.a9df34ee.js"><link rel="prefetch" href="/assets/js/60.f06adde2.js"><link rel="prefetch" href="/assets/js/61.170255a1.js"><link rel="prefetch" href="/assets/js/62.9d120050.js"><link rel="prefetch" href="/assets/js/63.70cced6b.js"><link rel="prefetch" href="/assets/js/64.577f3548.js"><link rel="prefetch" href="/assets/js/65.c037b29d.js"><link rel="prefetch" href="/assets/js/66.7dd1045f.js"><link rel="prefetch" href="/assets/js/67.d3aa4d6c.js"><link rel="prefetch" href="/assets/js/68.526dbb61.js"><link rel="prefetch" href="/assets/js/69.58269266.js"><link rel="prefetch" href="/assets/js/7.6609d4d6.js"><link rel="prefetch" href="/assets/js/70.64108f1b.js"><link rel="prefetch" href="/assets/js/71.1e95e0a6.js"><link rel="prefetch" href="/assets/js/72.42e7ec94.js"><link rel="prefetch" href="/assets/js/73.dad4e1c5.js"><link rel="prefetch" href="/assets/js/74.28ea286a.js"><link rel="prefetch" href="/assets/js/75.dd6d4c6f.js"><link rel="prefetch" href="/assets/js/76.ca6539df.js"><link rel="prefetch" href="/assets/js/77.feb13b0e.js"><link rel="prefetch" href="/assets/js/78.321e90e6.js"><link rel="prefetch" href="/assets/js/79.68eb8fcf.js"><link rel="prefetch" href="/assets/js/8.396d51fd.js"><link rel="prefetch" href="/assets/js/80.4edb5321.js"><link rel="prefetch" href="/assets/js/81.735d7e57.js"><link rel="prefetch" href="/assets/js/82.fa120bdf.js"><link rel="prefetch" href="/assets/js/83.bf755f94.js"><link rel="prefetch" href="/assets/js/84.9b32070c.js"><link rel="prefetch" href="/assets/js/85.592aca7c.js"><link rel="prefetch" href="/assets/js/86.4dcd9e73.js"><link rel="prefetch" href="/assets/js/87.a9e546aa.js"><link rel="prefetch" href="/assets/js/88.2a423212.js"><link rel="prefetch" href="/assets/js/89.5f455115.js"><link rel="prefetch" href="/assets/js/9.adb074c6.js"><link rel="prefetch" href="/assets/js/90.5202da0a.js"><link rel="prefetch" href="/assets/js/91.02cee99d.js"><link rel="prefetch" href="/assets/js/92.f16bad0b.js"><link rel="prefetch" href="/assets/js/93.f933634f.js"><link rel="prefetch" href="/assets/js/94.8e7b1d65.js"><link rel="prefetch" href="/assets/js/95.ee0e4a0a.js"><link rel="prefetch" href="/assets/js/96.e21d78c2.js"><link rel="prefetch" href="/assets/js/97.c87e514e.js"><link rel="prefetch" href="/assets/js/98.d123ac92.js"><link rel="prefetch" href="/assets/js/99.92d1b416.js">
    <link rel="stylesheet" href="/assets/css/0.styles.91f57736.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container no-sidebar" data-v-3ba18f14><div data-v-3ba18f14><div id="loader-wrapper" class="loading-wrapper" data-v-041fef5b data-v-3ba18f14 data-v-3ba18f14><div class="loader-main" data-v-041fef5b><div data-v-041fef5b></div><div data-v-041fef5b></div><div data-v-041fef5b></div><div data-v-041fef5b></div></div> <!----> <!----></div> <div class="password-shadow password-wrapper-out" style="display:none;" data-v-68139a52 data-v-3ba18f14 data-v-3ba18f14><h3 class="title" style="display:none;" data-v-68139a52 data-v-68139a52>JavaKeeper</h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-68139a52 data-v-68139a52><input type="password" value="" data-v-68139a52> <span data-v-68139a52>Konck! Knock!</span> <button data-v-68139a52>OK</button></label> <div class="footer" style="display:none;" data-v-68139a52 data-v-68139a52><span data-v-68139a52><i class="iconfont reco-theme" data-v-68139a52></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-68139a52>vuePress-theme-reco</a></span> <span data-v-68139a52><i class="iconfont reco-copyright" data-v-68139a52></i> <a data-v-68139a52><span data-v-68139a52>海星</span>
            
          <!---->
          2020
        </a></span></div></div> <div class="hide" data-v-3ba18f14><header class="navbar" data-v-3ba18f14><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">JavaKeeper</span></a> <div class="links"><div class="color-picker"><a class="color-button"><i class="iconfont reco-color"></i></a> <div class="color-picker-menu" style="display:none;"><div class="mode-options"><h4 class="title">Choose mode</h4> <ul class="color-mode-options"><li class="dark">dark</li><li class="auto active">auto</li><li class="light">light</li></ul></div></div></div> <div class="search-box"><i class="iconfont reco-search"></i> <input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/java/" class="nav-link"><i class="iconfont undefined"></i>
  Java
</a></div><div class="nav-item"><a href="/data-structure-algorithms/" class="nav-link"><i class="iconfont undefined"></i>
  数据结构与算法
</a></div><div class="nav-item"><a href="/data-store/" class="nav-link"><i class="iconfont undefined"></i>
  数据存储与缓存
</a></div><div class="nav-item"><a href="/interview/" class="nav-link"><i class="iconfont undefined"></i>
  直击面试
</a></div> <a href="https://github.com/Jstarfish/JavaKeeper" target="_blank" rel="noopener noreferrer" class="repo-link"><i class="iconfont reco-github"></i>
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask" data-v-3ba18f14></div> <aside class="sidebar" data-v-3ba18f14><div class="personal-info-wrapper" data-v-5f6acefd data-v-3ba18f14><!----> <h3 class="name" data-v-5f6acefd>
    海星
  </h3> <div class="num" data-v-5f6acefd><div data-v-5f6acefd><h3 data-v-5f6acefd>0</h3> <h6 data-v-5f6acefd>Article</h6></div> <div data-v-5f6acefd><h3 data-v-5f6acefd>0</h3> <h6 data-v-5f6acefd>Tag</h6></div></div> <hr data-v-5f6acefd></div> <nav class="nav-links"><div class="nav-item"><a href="/java/" class="nav-link"><i class="iconfont undefined"></i>
  Java
</a></div><div class="nav-item"><a href="/data-structure-algorithms/" class="nav-link"><i class="iconfont undefined"></i>
  数据结构与算法
</a></div><div class="nav-item"><a href="/data-store/" class="nav-link"><i class="iconfont undefined"></i>
  数据存储与缓存
</a></div><div class="nav-item"><a href="/interview/" class="nav-link"><i class="iconfont undefined"></i>
  直击面试
</a></div> <a href="https://github.com/Jstarfish/JavaKeeper" target="_blank" rel="noopener noreferrer" class="repo-link"><i class="iconfont reco-github"></i>
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav> <!----> </aside> <div class="password-shadow password-wrapper-in" style="display:none;" data-v-68139a52 data-v-3ba18f14><h3 class="title" style="display:none;" data-v-68139a52 data-v-68139a52></h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-68139a52 data-v-68139a52><input type="password" value="" data-v-68139a52> <span data-v-68139a52>Konck! Knock!</span> <button data-v-68139a52>OK</button></label> <div class="footer" style="display:none;" data-v-68139a52 data-v-68139a52><span data-v-68139a52><i class="iconfont reco-theme" data-v-68139a52></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-68139a52>vuePress-theme-reco</a></span> <span data-v-68139a52><i class="iconfont reco-copyright" data-v-68139a52></i> <a data-v-68139a52><span data-v-68139a52>海星</span>
            
          <!---->
          2020
        </a></span></div></div> <div data-v-3ba18f14><main class="page"><div class="page-title" style="display:none;"><h1 class="title"></h1> <div data-v-5d8dbdb4><i class="iconfont reco-account" data-v-5d8dbdb4><span data-v-5d8dbdb4>海星</span></i> <!----> <!----> <!----></div></div> <div class="theme-reco-content content__default" style="display:none;"><p><img src="/assets/img/nginx-index.2f334ee5.png" alt=""></p> <h1 id="nginx-学习一路向西"><a href="#nginx-学习一路向西" class="header-anchor">#</a> Nginx 学习一路向西</h1> <blockquote><p>Java大猿帅成长手册，<strong>GitHub</strong> <a href="https://github.com/Jstarfish/JavaEgg" target="_blank" rel="noopener noreferrer">JavaEgg<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> ，N线互联网开发必备技能兵器谱</p></blockquote> <h2 id="_1-nginx简介"><a href="#_1-nginx简介" class="header-anchor">#</a> 1. Nginx简介</h2> <h3 id="_1-1-nginx-概述"><a href="#_1-1-nginx-概述" class="header-anchor">#</a> 1.1 Nginx 概述</h3> <ul><li><p>NGINX是一个免费、开源、高性能、轻量级的HTTP和反向代理服务器，也是一个电子邮件（IMAP/POP3）代理服务器，其特点是占有内存少，并发能力强。 Nginx 因为它的稳定性、丰富的模块库、灵活的配置和较低的资源消耗而闻名 。目前应该是几乎所有项目建设必备。</p></li> <li><p>Nginx由内核和一系列模块组成，内核提供web服务的基本功能，如启用网络协议，创建运行环境，接收和分配客户端请求，处理模块之间的交互。Nginx的各种功能和操作都由模块来实现。Nginx的模块从结构上分为核心模块、基础模块和第三方模块。</p> <p>核心模块： HTTP模块、EVENT模块和MAIL模块</p> <p>基础模块： HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块</p> <p>第三方模块： HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块及用户自己开发的模块</p> <p>这样的设计使Nginx方便开发和扩展，也正因此才使得Nginx功能如此强大。Nginx的模块默认编译进nginx中，如果需要增加或删除模块，需要重新编译Nginx,这一点不如Apache的动态加载模块方便。如果有需要动态加载模块，可以使用由淘宝网发起的web服务器Tengine，在nginx的基础上增加了很多高级特性，完全兼容Nginx，已被国内很多网站采用。</p></li> <li><p>Nginx有很多扩展版本</p> <ul><li>开源版  <a href="http://nginx.org/" target="_blank" rel="noopener noreferrer">nginx.org<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li>商业版 <a href="https://www.nginx.com/" target="_blank" rel="noopener noreferrer">NGINX Plus<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li>淘宝网发起的Web服务器 <a href="http://tengine.taobao.org/" target="_blank" rel="noopener noreferrer">Tengine<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li>基于Nginx和Lua的Web平台 <a href="http://openresty.org/cn/" target="_blank" rel="noopener noreferrer">OpenResty<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></li></ul> <h3 id="_1-2-nginx-作为-web-服务器"><a href="#_1-2-nginx-作为-web-服务器" class="header-anchor">#</a> 1.2 Nginx 作为 web 服务器</h3> <p>Web服务器也称为WWW(WORLD WIDE WEB)服务器，主要功能是提供网上信息浏览服务，常常以B/S（Browser/Server）方式提供服务。</p> <ul><li>应用层使用HTTP协议。</li> <li>HTML文档格式。</li> <li>浏览器统一资源定位器(URL)。</li></ul> <p>Nginx 可以作为静态页面的 web 服务器，同时还支持 CGI 协议的动态语言，比如 perl、php 等，但是不支持 java。Java 程序一般都通过与 Tomcat 配合完成。</p> <p>作为一名Java猿帅，肯定要理解下Nginx和Tomcat的区别了：</p> <p><strong>Nginx、Apache和Tomcat</strong></p> <ul><li><p>Nginx—— 由俄罗斯程序员Igor Sysoev所开发的轻量级、高并发HTTP服务器；</p></li> <li><p><a href="/nginx/httpd.apache.org/">Apache HTTP Server Project</a>，一个Apache基金会下的HTTP服务项目，和Nginx功能类似；</p></li> <li><p><a href="http://tomcat.apache.org/" target="_blank" rel="noopener noreferrer">Apache Tomcat<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> ，则是Apache基金会下的另外一个项目，是一个<strong>Application Server</strong>，更准确的说是一个</p> <p>servlet应用容器，与Apache HTTP Server和Nginx相比，Tomcat能够<strong>动态</strong>的生成资源并返回到客户端；</p></li></ul> <p>Apache HTTP Server和Nginx本身不支持生成动态页面，但它们可以通过其他模块来支持（例如通过Shell、PHP、Python脚本程序来动态生成内容）；</p> <p>一个 HTTP Server 关心的是 HTTP 协议层面的传输和访问控制，所以在 Apache/Nginx 上你可以看到代理、负载均衡等功能。客户端通过 HTTP Server 访问服务器上存储的资源（HTML 文件、图片文件等等）。通过 CGI 技术，也可以将处理过的内容通过 HTTP Server 分发，但是一个 HTTP Server 始终只是把服务器上的文件如实的通过 HTTP 协议传输给客户端。</p> <p>而应用服务器，则是一个应用执行的容器。它首先需要支持开发语言的运行（对于 Tomcat 来说，就是 Java），保证应用能够在应用服务器上正常运行。其次，需要支持应用相关的规范，例如类库、安全方面的特性。对于 Tomcat 来说，就是需要提供 JSP/Sevlet 运行需要的标准类库、Interface 等。为了方便，应用服务器往往也会集成 HTTP Server 的功能，但是不如专业的 HTTP Server 那么强大，所以应用服务器往往是运行在 HTTP Server 的背后，执行应用，将动态的内容转化为静态的内容之后，通过 HTTP Server 分发到客户端。</p> <h3 id="_1-3-正向代理"><a href="#_1-3-正向代理" class="header-anchor">#</a> 1.3 正向代理</h3> <p>正向代理：如果把局域网外的 Internet 想象成一个巨大的资源库，则局域网中的客户端要访 问 Internet，则需要通过代理服务器来访问，这种代理服务就称为正向代理。</p> <p><strong>正向代理“代理”的是客户端</strong>。</p> <p>比如你想去google看个“动作片”，可国内不允许呀，就需要找翻墙代理，这个就是所谓的”正向代理“。</p> <p><img src="/assets/img/forward-proxy.da80da62.png" alt="forward-proxy"></p> <h3 id="_1-4-反向代理-与-负载均衡"><a href="#_1-4-反向代理-与-负载均衡" class="header-anchor">#</a> 1.4 反向代理 与 负载均衡</h3> <p>反向代理正好与正向代理相反，反向代理是指以代理服务器来接收Internet上的连接请求，然后将请求转发到内部网络上的服务器，并将服务器上得到的结果返回给客户端，此时代理服务器对外表现就是一个服务器，客户端对代理是无感知的。</p> <p><strong>反向代理“代理”的是服务端</strong>。</p> <p>再比如，你想本本分分的在“优酷”上看个“爱情片”，youku.com会把你的请求分发到存放片片的那台机器上，这个就是所谓的”反向代理“。</p> <p><img src="/assets/img/reverse-proxy.8237c4f6.png" alt="reverse-proxy"></p> <p><strong>为什么使用反向代理</strong></p> <ul><li>保护和隐藏原始资源服务器</li> <li>加密和SSL加速</li> <li>通过缓存静态资源，加速Web请求</li> <li>实现负载均衡</li></ul> <h4 id="负载均衡"><a href="#负载均衡" class="header-anchor">#</a> <strong>负载均衡</strong></h4> <p>TODO: 留一个负载均衡详细介绍传送门</p> <h4 id="地址重定向"><a href="#地址重定向" class="header-anchor">#</a> 地址重定向</h4> <p>Nginx 的Rewrite主要的功能就是实现URL重写</p> <p>比如输入360.com  跳转到了360.cn，baidu.cn跳转到了baidu.com</p> <h3 id="_1-5-动静分离"><a href="#_1-5-动静分离" class="header-anchor">#</a> 1.5 动静分离</h3> <p>为了加快网站的解析速度，可以把动态页面和静态页面由不同的服务器来解析，加快解析速度，降低原来单个服务器的压力。 这里指的就是让动态程序（Java、PHP）去访问应用服务器，让缓存、图片、JS、CSS等去访问Nginx。</p> <hr> <h2 id="_2-nginx-安装"><a href="#_2-nginx-安装" class="header-anchor">#</a> 2. Nginx 安装</h2> <ol><li><p><a href="http://nginx.org/" target="_blank" rel="noopener noreferrer">下载Nginx<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <div class="language-sh extra-class"><pre class="language-sh"><code><span class="token function">wget</span> http://nginx.org/download/nginx-1.16.1.tar.gz 
</code></pre></div></li> <li><p>安装需要编译的插件</p> <ul><li><p>用于编译c、c++代码的GCC；</p></li> <li><p>用c语言编写的正则表达式函数库Pcre(使用rewrite模块)；</p></li> <li><p>用于数据压缩的函式库的Zlib；</p></li> <li><p>安全套接字层密码库OpenSSL（启用SSL支持）</p></li></ul> <div class="language-sh extra-class"><pre class="language-sh"><code>yum <span class="token function">install</span> gcc c++                                          
yum <span class="token function">install</span> -y pcre pcre-devel                          
yum <span class="token function">install</span> -y zlib zlib-devel                           
yum <span class="token function">install</span> -y openssl openssl-devel   
</code></pre></div></li> <li><p>解压、配置（Nginx支持各种配置选项,文末一一列出 <a href="#Nginx%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9">Nginx配置选项</a> ）、编译、安装nginx</p> <div class="language-sh extra-class"><pre class="language-sh"><code><span class="token function">tar</span> -zxvf nginx-1.15.tar.gz <span class="token builtin class-name">cd</span> nginx-1.16.1
<span class="token builtin class-name">cd</span> nginx-1.16.1
./configure
<span class="token function">make</span> <span class="token operator">&amp;&amp;</span> <span class="token function">sudo</span> <span class="token function">make</span> <span class="token function">install</span> 
</code></pre></div></li> <li><p>启动、重启、关闭</p> <div class="language-sh extra-class"><pre class="language-sh"><code><span class="token builtin class-name">cd</span> /usr/local/nginx/ 
<span class="token builtin class-name">cd</span> sbin
./nginx
<span class="token comment">#关闭命令 </span>
./nginx -s stop
<span class="token comment">#重启，热部署</span>
./nginx -s reload
<span class="token comment">#修改配置文件后也别嘚瑟，反正我会动不动就写错，检查修改的nginx.conf配置是否正确</span>
./nginx -t
</code></pre></div><p><img src="/assets/img/nginx-t.32a9727a.png" alt="nginx-t"></p></li> <li><p>验证（浏览器输入ip）</p> <p><img src="/assets/img/welcome-nginx.4ab06374.png" alt="welcome-nginx"></p></li></ol> <hr> <h2 id="_3-配置文件"><a href="#_3-配置文件" class="header-anchor">#</a> 3. 配置文件</h2> <p>nginx.conf 配置文件主要分为三部分：全局块、events块、https块。</p> <p><strong>Nginx配置语法：</strong></p> <ul><li>配置文件由指令和指令块构成</li> <li>每条指令以分号（;）结尾，指令和参数间以空格符分隔</li> <li>指令块以大括号{}将多条指令组织在一起</li> <li>include语句允许组合多个配置文件以提高可维护性</li> <li>使用 # 添加注释</li> <li>使用 $ 定义变量</li> <li>部分指令的参数支持正则表达式</li></ul> <h4 id="_3-1-全局块"><a href="#_3-1-全局块" class="header-anchor">#</a> 3.1 全局块</h4> <p>全局配置部分用来配置对整个server都有效的参数。主要会设置一些影响 nginx 服务器整体运行的配置指令，主要包括配置运行 Nginx 服务器的用户（组）、允许生成的 worker process 数，进程 PID 存放路径、日志存放路径和类型以 及配置文件的引入等。 示例：</p> <div class="language- extra-class"><pre class="language-text"><code>user nobody;
worker_processes  4;
error_log  /data/nginx/logs/error.log  notice; 
</code></pre></div><h4 id="_3-2-events-块"><a href="#_3-2-events-块" class="header-anchor">#</a> 3.2 events 块</h4> <p>events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接，常用的设置包括是否开启对多 work process 下的网络连接进行序列化，是否允许同时接收多个网络连接，选取哪种事件驱动模型来处理连接请求，每个 word process 可以同时支持的最大连接数等。</p> <div class="language- extra-class"><pre class="language-text"><code>events {
	#每个 work process 支持的最大连接数为 1024.
    worker_connections  1024;
}
</code></pre></div><h4 id="_3-3-http-块"><a href="#_3-3-http-块" class="header-anchor">#</a> 3.3 http 块</h4> <p>这算是 Nginx 服务器配置中最频繁的部分，代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。 需要注意的是：http 块也可以包括 http 全局块、server 块。</p> <h5 id="_3-3-1-http-全局块"><a href="#_3-3-1-http-全局块" class="header-anchor">#</a> 3.3.1 http 全局块</h5> <p>http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。</p> <div class="language- extra-class"><pre><code>http {
    include       mime.types;
    default_type  application/octet-stream;
	sendfile        on;
	keepalive_timeout  65;
</code></pre></div><h5 id="_3-3-2-server-块"><a href="#_3-3-2-server-块" class="header-anchor">#</a> 3.3.2 server 块</h5> <p>这块和虚拟主机有密切关系，虚拟主机从用户角度看，和一台独立的硬件主机是完全一样的，该技术的产生是为了 节省互联网服务器硬件成本。</p> <p>每个 http 块可以包括多个 server 块，而每个 server 块就相当于一个虚拟主机。</p> <p>而每个 server 块也分为全局 server 块，以及可以同时包含多个 locaton 块。</p> <ul><li><p><strong>全局 server 块</strong></p> <p>也被叫做“虚拟服务器”部分，它描述的是一组根据不同server_name指令逻辑分割的资源，这些虚拟服务器响应HTTP请求，因此都包含在http部分。最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。</p> <div class="language- extra-class"><pre><code>server {
  listen       80;
  #server_name也支持通配符，*.example.com、www.example.*、.example.com
  server_name  localhost;
  #charset koi8-r;
  #access_log  logs/host.access.log  main;
</code></pre></div></li> <li><p><strong>location 块</strong></p> <p>一个 server 块可以配置多个 location 块。</p> <p>这块的主要作用是基于 Nginx 服务器接收到的请求字符串（例如 server_name/uri-string），对虚拟主机名称 （也可以是 IP 别名）之外的字符串（例如 前面的 /uri-string）进行匹配，对特定的请求进行处理。地址定向、数据缓存和应答控制等功能，还有许多第三方模块的配置也在这里进行。</p> <p><strong>location 指令说明</strong></p> <p>该指令用于匹配 URL。</p> <p>语法如下：<code>location [ = | ~ | ~* | ^~] uri{}</code></p> <ul><li>= ：该修饰符使用精确匹配并且终止搜索。</li> <li>~：该修饰符使用区分大小写的正则表达式匹配。</li> <li>~*：该修饰符使用不区分大小写的正则表达式匹配。</li> <li>^~：用于不含正则表达式的 uri 前，要求 Nginx 服务器找到标识 uri 和请求字 符串匹配度最高的 location 后，立即使用此 location 处理请求，而不再使用 location 块中的正则 uri 和请求字符串做匹配。</li></ul> <p>?&gt; <strong>Tip</strong>  注意：如果 uri 包含正则表达式，则必须要有 ~ 或者 ~* 标识。</p> <p>当一个请求进入时，URI将会被检测匹配一个最佳的location。</p> <ul><li>没有正则表达式的location被作为最佳的匹配，独立于含有正则表达式的location顺序；</li> <li><strong>在配置文件中按照查找顺序进行正则表达式匹配</strong>。在查找到第一个正则表达式匹配之后结束查找。由这个最佳的location提供请求处理。</li></ul> <div class="language- extra-class"><pre class="language-text"><code> location / {
 	root   html;
    index  index.html index.htm;
    }
  
  #error_page  404              /404.html;
  
  # redirect server error pages to the static page /50x.html
  #
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
  	root   html;
  }
  location / {
      #try_files指令将会按照给定的参数顺序进行匹配尝试
      try_files $uri $uri/ /index.html;
  }
</code></pre></div></li></ul> <h4 id="nginx-conf-详细配置"><a href="#nginx-conf-详细配置" class="header-anchor">#</a> nginx.conf 详细配置</h4> <div class="language- extra-class"><pre><code>#定义Nginx运行的用户和用户组
user www www; 

#nginx进程数，通常设置成和cpu的数量相等
worker_processes 4; 

#全局错误日志定义类型，[debug | info | notice | warn | error | crit]
#error_log  /data/nginx/logs/error.log;
#error_log  /data/nginx/logs/error.log  notice;

#日志文件存放路径 access_log path [format [buffer=size | off]]
access_log /data/nginx/logs/lazyegg.com/web/access.log combinedio;

#进程pid文件
#pid        logs/nginx.pid;

#指定进程可以打开的最大描述符：数目
#工作模式与连接数上限
##这个指令是指当一个nginx进程打开的最多文件描述符数目，理论值应该是最多打开文件数（ulimit -n）与nginx进程数相除，但是nginx分配请求并不是那么均匀，所以最好与ulimit -n 的值保持一致。
#这是因为nginx调度时分配请求到进程并不是那么的均衡，所以假如填写10240，总并发量达到3-4万时就有进程可能超过10240了，这时会返回502错误。
worker_rlimit_nofile 65535;

#################################  events  ###############################
events {
    #参考事件模型，use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型
    use epoll
    #单个进程最大连接数（最大连接数=连接数+进程数）
    worker_connections  1024;
    
    #keepalive 超时时间
    keepalive_timeout 60;
    
    #客户端请求头部的缓冲区大小。
    client_header_buffer_size 4k;
    
    #这个将为打开文件指定缓存，默认是没有启用的，max指定缓存数量，建议和打开文件数一致，inactive是指经过多长时间文件没被请求后删除缓存。
    open_file_cache max=65535 inactive=60s;
    #这个是指多长时间检查一次缓存的有效信息。
    open_file_cache_valid 80s;
    #open_file_cache指令中的inactive参数时间内文件的最少使用次数，如果超过这个数字，文件描述符一直是在缓存中打开的，如上例，如果有一个文件在inactive时间内一次没被使用，它将被移除。
    open_file_cache_min_uses 1;
    
    #语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件是记录cache错误.
    open_file_cache_errors on;
}

##############################   http    ##################################

#设定http服务器，利用它的反向代理功能提供负载均衡支持
http{
    #文件扩展名与文件类型映射表
    include mime.types;
    
    #默认文件类型
    default_type application/octet-stream;
    
    #默认编码
    charset utf-8;
    
    #服务器名字的hash表大小
    server_names_hash_bucket_size 128;
    
    #客户端请求头部的缓冲区大小。
    client_header_buffer_size 32k;
    
    #客户请求头缓冲大小。
    large_client_header_buffers 4 64k;
    
    #允许客户端请求的最大单个文件字节数
    client_max_body_size 8m;
    
    #开启高效文件传输模式，sendfile指令指定nginx是否调用sendfile函数来输出文件，对于普通应用设为 on，如果用来进行下载等应用磁盘IO重负载应用，可设置为off，以平衡磁盘与网络I/O处理速度，降低系统的负载。注意：如果图片显示不正常把这个改成off。
    sendfile on;
    
    #开启目录列表访问，适合下载服务器，默认关闭。
    autoindex on;
    
    #此选项允许或禁止使用socke的TCP_CORK的选项，此选项仅在使用sendfile的时候使用
    tcp_nopush on;
     
    tcp_nodelay on;
    
    #长连接超时时间，单位是秒
    keepalive_timeout 120;
    
    #FastCGI相关参数是为了改善网站的性能：减少资源占用，提高访问速度。下面参数看字面意思都能理解。
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;
    
    #gzip模块设置
    gzip on; #开启gzip压缩输出
    gzip_min_length 1k;    #最小压缩文件大小
    gzip_buffers 4 16k;    #压缩缓冲区
    gzip_http_version 1.0; #压缩版本（默认1.1，前端如果是squid2.5请使用1.0）
    gzip_comp_level 2;     #压缩等级
    gzip_types text/plain application/x-javascript text/css application/xml;    #压缩类型，默认就已经包含textml，所以下面就不用再写了，写上去也不会有问题，但是会有一个warn。
    gzip_vary on;

    #开启限制IP连接数的时候需要使用
    #limit_zone crawler $binary_remote_addr 10m;
    
    #负载均衡配置
    upstream lazyegg.net {
  
        #upstream的负载均衡，weight是权重，可以根据机器配置定义权重。weigth参数表示权值，权值越高被分配到的几率越大。
        server 192.168.80.121:80 weight=3;
        server 192.168.80.122:80 weight=2;
        server 192.168.80.123:80 weight=3;

        #nginx的upstream目前支持4种方式的分配
        #1、轮询（默认）
        #每个请求按时间顺序逐一分配到不同的后端服务器，如果后端服务器down掉，能自动剔除。
        #2、weight
        #指定轮询几率，weight和访问比率成正比，用于后端服务器性能不均的情况。
        #例如：
        #upstream bakend {
        #    server 192.168.0.14 weight=10;
        #    server 192.168.0.15 weight=10;
        #}
        #2、ip_hash
        #每个请求按访问ip的hash结果分配，这样每个访客固定访问一个后端服务器，可以解决session的问题。
        #例如：
        #upstream bakend {
        #    ip_hash;
        #    server 192.168.0.14:88;
        #    server 192.168.0.15:80;
        #}
        #3、fair（第三方）
        #按后端服务器的响应时间来分配请求，响应时间短的优先分配。
        #upstream backend {
        #    server server1;
        #    server server2;
        #    fair;
        #}
        #4、url_hash（第三方）
        #按访问url的hash结果来分配请求，使每个url定向到同一个后端服务器，后端服务器为缓存时比较有效。
        #例：在upstream中加入hash语句，server语句中不能写入weight等其他的参数，hash_method是使用的hash算法
        #upstream backend {
        #    server squid1:3128;
        #    server squid2:3128;
        #    hash $request_uri;
        #    hash_method crc32;
        #}

        #tips:
        #upstream bakend{#定义负载均衡设备的Ip及设备状态}{
        #    ip_hash;
        #    server 127.0.0.1:9090 down;
        #    server 127.0.0.1:8080 weight=2;
        #    server 127.0.0.1:6060;
        #    server 127.0.0.1:7070 backup;
        #}
        #在需要使用负载均衡的server中增加 proxy_pass http://bakend/;

        #每个设备的状态设置为:
        #1.down表示单前的server暂时不参与负载
        #2.weight为weight越大，负载的权重就越大。
        #3.max_fails：允许请求失败的次数默认为1.当超过最大次数时，返回proxy_next_upstream模块定义的错误
        #4.fail_timeout:max_fails次失败后，暂停的时间。
        #5.backup： 其它所有的非backup机器down或者忙的时候，请求backup机器。所以这台机器压力会最轻。

        #nginx支持同时设置多组的负载均衡，用来给不用的server来使用。
        #client_body_in_file_only设置为On 可以讲client post过来的数据记录到文件中用来做debug
        #client_body_temp_path设置记录文件的目录 可以设置最多3层目录
        #location对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡
    }
    
     #虚拟主机的配置
    server {
        #监听端口
        listen 80;

        #域名可以有多个，用空格隔开
        server_name lazyegg.net;
        #默认入口文件名称
        index index.html index.htm index.php;
        root /data/www/lazyegg;

        #对******进行负载均衡
        location ~ .*.(php|php5)?$
        {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi.conf;
        }
         
        #图片缓存时间设置
        location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires 10d;
        }
         
        #JS和CSS缓存时间设置
        location ~ .*.(js|css)?$
        {
            expires 1h;
        }
         
        #日志格式设定
        #$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址；
        #$remote_user：用来记录客户端用户名称；
        #$time_local： 用来记录访问时间与时区；
        #$request： 用来记录请求的url与http协议；
        #$status： 用来记录请求状态；成功是200，
        #$body_bytes_sent ：记录发送给客户端文件主体内容大小；
        #$http_referer：用来记录从那个页面链接访问过来的；
        #$http_user_agent：记录客户浏览器的相关信息；
        #通常web服务器放在反向代理的后面，这样就不能获取到客户的IP地址了，通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中，可以增加x_forwarded_for信息，用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
        log_format access '$remote_addr - $remote_user [$time_local] &quot;$request&quot; '
        '$status $body_bytes_sent &quot;$http_referer&quot; '
        '&quot;$http_user_agent&quot; $http_x_forwarded_for';
         
        #定义本虚拟主机的访问日志
        access_log  /usr/local/nginx/logs/host.access.log  main;
        access_log  /usr/local/nginx/logs/host.access.404.log  log404;
         
        #对 &quot;/connect-controller&quot; 启用反向代理
        location /connect-controller {
            proxy_pass http://127.0.0.1:88; #请注意此处端口号不能与虚拟主机监听的端口号一样（也就是server监听的端口）
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
             
            #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             
            #以下是一些反向代理的配置，可选。
            proxy_set_header Host $host;

            #允许客户端请求的最大单文件字节数
            client_max_body_size 10m;

            #缓冲区代理缓冲用户端请求的最大字节数，
            #如果把它设置为比较大的数值，例如256k，那么，无论使用firefox还是IE浏览器，来提交任意小于256k的图片，都很正常。如果注释该指令，使用默认的client_body_buffer_size设置，也就是操作系统页面大小的两倍，8k或者16k，问题就出现了。
            #无论使用firefox4.0还是IE8.0，提交一个比较大，200k左右的图片，都返回500 Internal Server Error错误
            client_body_buffer_size 128k;

            #表示使nginx阻止HTTP应答代码为400或者更高的应答。
            proxy_intercept_errors on;

            #后端服务器连接的超时时间_发起握手等候响应超时时间
            #nginx跟后端服务器连接超时时间(代理连接超时)
            proxy_connect_timeout 90;

            #后端服务器数据回传时间(代理发送超时)
            #后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
            proxy_send_timeout 90;

            #连接成功后，后端服务器响应时间(代理接收超时)
            #连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理（也可以说是后端服务器处理请求的时间）
            proxy_read_timeout 90;

            #设置代理服务器（nginx）保存用户头信息的缓冲区大小
            #设置从被代理服务器读取的第一部分应答的缓冲区大小，通常情况下这部分应答中包含一个小的应答头，默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小，不过可以将其设置为更小
            proxy_buffer_size 4k;

            #proxy_buffers缓冲区，网页平均在32k以下的设置
            #设置用于读取应答（来自被代理服务器）的缓冲区数目和大小，默认情况也为分页大小，根据操作系统的不同可能是4k或者8k
            proxy_buffers 4 32k;

            #高负荷下缓冲大小（proxy_buffers*2）
            proxy_busy_buffers_size 64k;

            #设置在写入proxy_temp_path时数据的大小，预防一个工作进程在传递文件时阻塞太长
            #设定缓存文件夹大小，大于这个值，将从upstream服务器传
            proxy_temp_file_write_size 64k;
        }
        
        #本地动静分离反向代理配置
        #所有jsp的页面均交由tomcat或resin处理
        location ~ .(jsp|jspx|do)?$ {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8080;
        }
    }
}
</code></pre></div><hr> <h2 id="_4-nginx-配置实例"><a href="#_4-nginx-配置实例" class="header-anchor">#</a> 4. Nginx 配置实例</h2> <h3 id="_4-1-反向代理demo1"><a href="#_4-1-反向代理demo1" class="header-anchor">#</a> 4.1 反向代理demo1</h3> <p>实现效果：使用 nginx 反向代理，访问 test.com 直接跳转到自己的机器 127.0.0.1:8080</p> <ol><li>启动一个 tomcat，浏览器地址栏输入 127.0.0.1:8080，出现如下界面</li></ol> <p><img src="/assets/img/tomcat-index.2bf778ed.png" alt="tomcat-index"></p> <ol start="2"><li><p>通过修改本地 host 文件（C:\Windows\System32\drivers\etc），添加<code>127.0.0.1 www.12345.com</code>将 www.12345.com 映射到自己的机器ip上</p></li> <li><p>配置完成之后，我们便可以通过 www.test.com:8080 访问到第一步出现的 Tomcat 初始界面。那么如何只需要输入 www.12345.com 便可以跳转到 Tomcat 初始界面呢？便用到 nginx 的反向代理。</p></li> <li><p>修改nginx.conf 配置文件，增加如下配置 <code>proxy_pass</code></p></li></ol> <div class="language- extra-class"><pre class="language-text"><code>    server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
               proxy_pass http://127.0.0.1:8080;
        }

</code></pre></div><ol start="5"><li>如上配置，我们监听 80 端口，访问域名为 www.12345.com，不加端口号时默认为 80 端口，故访问该域名时会跳转到 127.0.0.1:8080 路径上。在浏览器端输入 www.12345.com 结果如下：</li></ol> <p><img src="/assets/img/nginx-demo1.7e13f536.png" alt="nginx-demo1"></p> <h3 id="_4-2-反向代理demo2"><a href="#_4-2-反向代理demo2" class="header-anchor">#</a> 4.2 反向代理demo2</h3> <p>实现效果：使用 nginx 反向代理，根据访问的路径跳转到不同端口的服务中</p> <p>访问 http://127.0.0.1/java/ 直接跳转到 127.0.0.1:8080</p> <p>访问 http://127.0.0.1/egg/ 直接跳转到 127.0.0.1:8081</p> <ol><li><p>在服务器上起两个tomcat，修改其中一个端口号为8081； 在tomcat/webapps/目录下的各加两个文件夹，并随便写个html页面），我建的是java/index.html和egg/index.html</p></li> <li><p>修改nginx.conf，在http块中添加serve{}</p> <div class="language- extra-class"><pre class="language-text"><code>server {
        listen       80;
        server_name  localhost;

        location ~ /java/ {
            proxy_pass http://127.0.0.1:8080;
        }

        location /egg/ {
            proxy_pass http://127.0.0.1:8081;
        }
}
</code></pre></div></li> <li><p>重启nginx，验证效果</p> <p><img src="/assets/img/demo2.03c287f3.png" alt=""></p></li></ol> <h3 id="_4-3-nginx-配置-负载均衡"><a href="#_4-3-nginx-配置-负载均衡" class="header-anchor">#</a> 4.3 Nginx 配置-负载均衡</h3> <p>随着互联网信息的爆炸性增长，负载均衡（load balance）已经不再是一个很陌生的话题， 顾名思义，负载均衡即是将负载分摊到不同的服务单元，既保证服务的可用性，又保证响应足够快，给用户很好的体验。快速增长的访问量和数据流量催生了各式各样的负载均衡产品， 很多专业的负载均衡硬件提供了很好的功能，但却价格不菲，这使得负载均衡软件大受欢迎， nginx 就是其中的一个，在 linux 下有 Nginx、LVS、Haproxy 等等服务可以提供负载均衡服务。</p> <p>Nginx的负载均衡是proxy模块和upstream模块搭配实现的。upstream模块将会启用一个新的配置区段，在该区段定义了一组上游服务器。</p> <p>实现效果：配置负载均衡</p> <ol><li><p>同时启动两个Tomcat（为了方便验证效果，修改tomcat端口号的同时，顺便将Tomcat默认欢迎页面apache-tomcat-9.0.29/webapps/ROOR目录下的index.jsp修改下，看下8081欢迎页的“蛋蛋”没）</p> <p><img src="/assets/img/nginx-tomcat.79dca8df.png" alt="nginx-tomcat"></p></li> <li><p>修改nginx.conf</p> <div class="language- extra-class"><pre class="language-text"><code>http {
    upstream myserver {
        server localhost:8080;
        server localhost:8081;
    }
    server {
        listen 80;
        location / {
            proxy_pass http://myserver;
        }
    }
}
</code></pre></div></li> <li><p>重启nginx，验证效果（默认轮询的方式，每次打开新窗口，8080和8081会交替出现，同一个窗口的话需要关闭浏览器缓存)</p></li></ol> <p><strong>Nginx 分配策略：</strong></p> <ol><li><p>轮询（默认） 每个请求按时间顺序逐一分配到不同的后端服务器，如果后端服务器 down 掉，能自动剔除</p></li> <li><p>weight weight 代表权,重默认为 1,权重越高被分配的客户端越多 指定轮询几率，weight 和访问比率成正比，用于后端服务器性能不均的情况。 例如：</p> <div class="language- extra-class"><pre class="language-text"><code> upstream server_pool{ 
	server 192.168.5.21 weight=10; 
	server 192.168.5.22 weight=10; } 
</code></pre></div></li> <li><p>ip_hash 每个请求按访问 ip 的 hash 结果分配，这样每个访客固定访问一个后端服务器，可以解决 session 的问题。 例如：</p> <div class="language- extra-class"><pre class="language-text"><code>upstream server_pool{
	ip_hash; server 192.168.5.21:80; 
	server 192.168.5.22:80; 
} 
</code></pre></div></li> <li><p>fair（第三方） 按后端服务器的响应时间来分配请求，响应时间短的优先分配。</p> <div class="language- extra-class"><pre class="language-text"><code>upstream server_pool{ 
	server 192.168.5.21:80;
    server 192.168.5.22:80; fair;
 } 
</code></pre></div></li></ol> <h3 id="_4-4-nginx-配置-动静分离"><a href="#_4-4-nginx-配置-动静分离" class="header-anchor">#</a> 4.4 Nginx 配置-动静分离</h3> <p>Nginx 动静分离简单来说就是把动态跟静态请求分开，不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开，可以理解成使用 Nginx 处理静态页面，Tomcat 处理动态页面。动静分离从目前实现角度来讲大致分为两种， 一种是纯粹把静态文件独立成单独的域名，放在独立的服务器上，也是目前主流推崇的方案； 另外一种方法就是动态跟静态文件混合在一起发布，通过 nginx 来分开。 通过 location 指定不同的后缀名实现不同的请求转发。通过 expires 参数设置，可以使浏览器缓存过期时间，减少与服务器之前的请求和流量。具体 Expires 定义：是给一个资 源设定一个过期时间，也就是说无需去服务端验证，直接通过浏览器自身确认是否过期即可， 所以不会产生额外的流量。此种方法非常适合不经常变动的资源。（如果经常更新的文件， 不建议使用 Expires 来缓存），我这里设置 3d，表示在这 3 天之内访问这个 URL，发送 一个请求，比对服务器该文件最后更新时间没有变化，则不会从服务器抓取，返回状态码 304，如果有修改，则直接从服务器重新下载，返回状态码 200。</p> <p><img src="/assets/img/nginx-separation.abf3e61e.png" alt="nginx-separation.png"></p> <ol><li><p>服务器找个目录存放自己的静态文件</p> <p><img src="" alt=""></p></li> <li><p>修改nginx.conf</p> <div class="language- extra-class"><pre class="language-text"><code>    server {
        listen       80;
        server_name  localhost;
        location /static/ {
            root   /usr/data/www;
        }
        location /image/ {
             root /usr/data/;
             autoindex on;
        }
</code></pre></div></li> <li><p><code>./nginx -s reload</code>，验证效果</p> <p><img src="/assets/img/nginx-static.1854c77b.png" alt="image-20191211172217503"></p></li></ol> <p>添加监听端口、访问名字 重点是添加 location， 最后检查 Nginx 配置是否正确即可，然后测试动静分离是否成功，之需要删除后端 tomcat 服务器上的某个静态文件，查看是否能访问，如果可以访问说明静态资源 nginx 直接返回 了，不走后端 tomcat 服务器</p> <h3 id="_4-5-nginx的rewrite"><a href="#_4-5-nginx的rewrite" class="header-anchor">#</a> 4.5  Nginx的Rewrite</h3> <p>Rewrite是Nginx服务器提供的一个重要的功能，它可以实现URL重写和重定向功能。</p> <p>场景：</p> <ul><li>URL访问跳转，支持开发设计。 页面跳转、兼容性支持(新旧版本更迭)、展示效果(网址精简)等</li> <li>SEO优化(Nginx伪静态的支持)</li> <li>后台维护、流量转发等</li> <li>安全(动态界面进行伪装)</li></ul> <p>该指令是通过正则表达式的使用来改变URI。可以同时存在一个或多个指令。需要按照顺序依次对URL进行匹配和处理。</p> <p>该指令可以在server块或location块中配置，其基本语法结构如下：</p> <div class="language- extra-class"><pre class="language-text"><code>rewrite regex replacement [flag];
</code></pre></div><ol><li><p>采用反向代理demo2中的例子，修改nginx.conf(只多加了一行rewrite)</p> <div class="language- extra-class"><pre class="language-text"><code>server {
        listen       80;
        server_name  localhost;

        location /java/ {
            proxy_pass http://127.0.0.1:8080;
            rewrite ^/java /egg/ redirect;
        }

        location /egg/ {
            proxy_pass http://127.0.0.1:8081;
        }
}

</code></pre></div></li> <li><p><code>./nginx -s reload</code>，验证效果（输入ip/java/被重定向到了egg）</p> <p><img src="/assets/img/nginx-rewrite.b590f228.jpg" alt=""></p></li></ol> <p>rewrite指令可以在server块或location块中配置，其基本语法结构如下：</p> <div class="language- extra-class"><pre class="language-text"><code>rewrite regex replacement [flag];
</code></pre></div><ul><li><strong>rewrite</strong>的含义：该指令是实现URL重写的指令。</li> <li><strong>regex</strong>的含义：用于匹配URI的正则表达式。</li> <li><strong>replacement</strong>：将regex正则匹配到的内容替换成 replacement。</li> <li><strong>flag: flag</strong>标记，flag有如下值：
<ul><li><strong>last:</strong> 本条规则匹配完成后，继续向下匹配新的location URI 规则。(不常用)</li> <li><strong>break:</strong> 本条规则匹配完成即终止，不再匹配后面的任何规则(不常用)。</li> <li><strong>redirect:</strong> 返回302临时重定向，浏览器地址会显示跳转新的URL地址。</li> <li><strong>permanent:</strong> 返回301永久重定向。浏览器地址会显示跳转新的URL地址。</li></ul></li></ul> <div class="language- extra-class"><pre class="language-text"><code>rewrite ^/(.*) http://www.360.cn/$1 permanent;
</code></pre></div><h3 id="_4-6-nginx-高可用"><a href="#_4-6-nginx-高可用" class="header-anchor">#</a> 4.6 Nginx 高可用</h3> <p>如果将Web服务器集群当做一个城池，那么负载均衡服务器就相当于城门。如果“城门”关闭了，与外界的通道就断了。如果只有一台Nginx负载服务器，当故障宕机的时候，就会导致整个网站无妨访问。所以我们需要两台以上Nginx来实现故障转移和高可用。</p> <p><img src="/assets/img/nginx-availability.889ef81f.png" alt="nginx-availability"></p> <h4 id="配置高可用"><a href="#配置高可用" class="header-anchor">#</a> 配置高可用</h4> <p><strong>双机热备方案</strong></p> <p>这种方案是国内企业中最为普遍的一种高可用方案，双机热备其实就是指一台服务器在提供服务，另一台为某服务的备用状态，当一台服务器不可用另外一台就会顶替上去。</p> <p><strong>keepalived是什么？</strong></p> <p><code>Keepalived</code>软件起初是专为<code>LVS</code>负载均衡软件设计的，用来管理并监控LVS集群系统中各个服务节点的状态，后来又加入了可以实现高可用的<code>VRRP (Virtual Router Redundancy Protocol ,虚拟路由器冗余协议）</code>功能。因此，<code>Keepalived</code>除了能够管理LVS软件外，还可以作为其他服务<code>（例如：Nginx、Haproxy、MySQL等）</code>的高可用解决方案软件</p> <p><strong>故障转移机制</strong></p> <p><code>Keepalived</code>高可用服务之间的故障切换转移，是通过<code>VRRP</code> 来实现的。
在 <code>Keepalived</code>服务正常工作时，主 <code>Master</code>节点会不断地向备节点发送（多播的方式）心跳消息，用以告诉备<code>Backup</code>节点自己还活着，当主 <code>Master</code>节点发生故障时，就无法发送心跳消息，备节点也就因此无法继续检测到来自主 <code>Master</code>节点的心跳了，于是调用自身的接管程序，接管主Master节点的 IP资源及服务。而当主 Master节点恢复时，备Backup节点又会释放主节点故障时自身接管的IP资源及服务，恢复到原来的备用角色。</p> <p><strong>实现</strong></p> <ol><li><p>准备两台安装Nginx和keepaliver(<code>yum install keepalived -y</code>)的服务器</p></li> <li><p>修改两台服务器上的/etc/keepalived/keepalived.conf</p> <div class="language- extra-class"><pre class="language-text"><code>#主机
#检测脚本
vrrp_script chk_http_port {
    script &quot;/usr/local/src/check_nginx.sh&quot; #心跳执行的脚本，检测nginx是否启动
    interval 2                          #（检测脚本执行的间隔，单位是秒）
    weight 2                            #权重
}
#vrrp 实例定义部分
vrrp_instance VI_1 {
    state MASTER            # 指定keepalived的角色，MASTER为主，BACKUP为备
    interface ens33         # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) 用ifconfig查看你具体的网卡
    virtual_router_id 66    # 虚拟路由编号，主从要一直
    priority 100            # 优先级，数值越大，获取处理请求的优先级越高
    advert_int 1            # 检查间隔，默认为1s(vrrp组播周期秒数)
    #授权访问
    authentication {
        auth_type PASS #设置验证类型和密码，MASTER和BACKUP必须使用相同的密码才能正常通信
        auth_pass 1111
    }
    track_script {
        chk_http_port            #（调用检测脚本）
    }
    virtual_ipaddress {
        192.168.16.150            # 定义虚拟ip(VIP)，可多设，每行一个
    }
}
</code></pre></div><div class="language- extra-class"><pre class="language-text"><code># 备机
#检测脚本
vrrp_script chk_http_port {
    script &quot;/usr/local/src/check_nginx.sh&quot; #心跳执行的脚本，检测nginx是否启动
    interval 2                          #（检测脚本执行的间隔）
    weight 2                            #权重
}
#vrrp 实例定义部分
vrrp_instance VI_1 {
    state BACKUP                        # 指定keepalived的角色，MASTER为主，BACKUP为备
    interface ens33                      # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) 用ifconfig查看你具体的网卡
    virtual_router_id 66                # 虚拟路由编号，主从要一直
    priority 99                         # 优先级，数值越大，获取处理请求的优先级越高
    advert_int 1                        # 检查间隔，默认为1s(vrrp组播周期秒数)
    #授权访问
    authentication {
        auth_type PASS #设置验证类型和密码，MASTER和BACKUP必须使用相同的密码才能正常通信
        auth_pass 1111
    }
    track_script {
        chk_http_port                   #（调用检测脚本）
    }
    virtual_ipaddress {
        192.168.16.150                   # 定义虚拟ip(VIP)，可多设，每行一个
    }
}
</code></pre></div></li> <li><p>新建检测脚本(<code>chmod 775 check_nginx.sh</code>)</p> <div class="language- extra-class"><pre class="language-text"><code>#!/bin/bash
#检测nginx是否启动了
A=`ps -C nginx --no-header |wc -l`        
if [ $A -eq 0 ];then    #如果nginx没有启动就启动nginx                        
      systemctl start nginx                #重启nginx
      if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then    #nginx重启失败，则停掉keepalived服务，进行VIP转移
              killall keepalived                    
      fi
fi
</code></pre></div></li> <li><p>启动Nginx和keepalived(<code>systemctl start keepalived.service</code>)</p></li> <li><p>模拟Nginx故障（关闭主服务器Nginx），验证，仍可以通过配置的虚拟ip访问，ok</p></li></ol> <h2 id="_5-nginx-原理与优化参数配置"><a href="#_5-nginx-原理与优化参数配置" class="header-anchor">#</a> 5. Nginx 原理与优化参数配置</h2> <p>Nginx默认采用多进程工作方式，Nginx启动后，会运行一个master进程和多个worker进程。其中master充当整个进程组与用户的交互接口，同时对进程进行监护，管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。worker用来处理基本的网络事件，worker之间是平等的，他们共同竞争来处理来自客户端的请求</p> <p><img src="/assets/img/nginx-work.43492ec3.png" alt="nginx-work"></p> <h4 id="master-workers-的机制的好处"><a href="#master-workers-的机制的好处" class="header-anchor">#</a> master-workers 的机制的好处</h4> <ol><li>可以使用nginx-s reload 热部署</li> <li>每个worker是独立的进程，不需要加锁，省掉了锁带来的开销。采用独立的进程，可以让互相之间不会影响，一个进程退出后，其它进程还在工作，服务不会中断，master 进程则很快启动新的 worker 进程。</li></ol> <h4 id="需要设置多少个-worker"><a href="#需要设置多少个-worker" class="header-anchor">#</a> 需要设置多少个 worker</h4> <p>Nginx 同 redis 类似都采用了 io 多路复用机制，每个 worker 都是一个独立的进程，但每个进程里只有一个主线程，通过异步非阻塞的方式来处理请求，即使是千上万个请求也不在话下。每个 worker 的线程可以把一个 cpu 的性能发挥到极致。所以 <strong>worker 数和服务器的 cpu 数相等是最为适宜</strong>的。设少了会浪费 cpu，设多了会造成 cpu 频繁切换上下文带来的损耗。</p> <div class="language- extra-class"><pre class="language-text"><code>#设置 worker 数量。
 worker_processes 4 
#work 绑定 cpu(4 work 绑定 4cpu)。 
 worker_cpu_affinity 0001 0010 0100 1000 
#work 绑定 cpu (4 work 绑定 8cpu 中的 4 个) 。 
 worker_cpu_affinity 0000001 00000010 00000100 00001000
</code></pre></div><h4 id="连接数-worker-connection"><a href="#连接数-worker-connection" class="header-anchor">#</a> 连接数 worker_connection</h4> <p>这个值是表示每个 worker 进程所能建立连接的最大值，所以，一个 nginx 能建立的最大连接数，应该是 worker_connections * worker_processes。当然，这里说的是最大连接数，对于 HTTP 请 求 本 地 资 源 来 说 ， 能 够 支 持 的 最 大 并 发 数 量 是 worker_connections * worker_processes，如果是支持 http1.1 的浏览器每次访问要占两个连接，所以普通的静态访 问最大并发数是： worker_connections * worker_processes /2，而如果是 HTTP 作 为反向代理来说，最大并发数量应该是 worker_connections * worker_processes/4。因为作为反向代理服务器，每个并发会建立与客户端的连接和与后端服 务的连接，会占用两个连接。</p> <h4 id="nginx请求处理流程"><a href="#nginx请求处理流程" class="header-anchor">#</a> Nginx请求处理流程</h4> <p><img src="/assets/img/nginx-process.1c0e072b.png" alt="nginx-process"></p> <hr> <h2 id="_6-nginx模块开发"><a href="#_6-nginx模块开发" class="header-anchor">#</a> 6. Nginx模块开发</h2> <p>由于Nginx的模块化特性，所以可以支持模块配置，也可以自定义模块，Nginx的模块开发，程序员目前还不需要太深入</p> <p><strong>Nginx模块分类</strong></p> <p><img src="/assets/img/nginx-module.384da8f4.png" alt="nginx-module"></p> <h4 id="nginx配置选项"><a href="#nginx配置选项" class="header-anchor">#</a> Nginx配置选项</h4> <p>解压nginx后的配置操作示例</p> <div class="language-sh extra-class"><pre class="language-sh"><code>./configure --prefix<span class="token operator">=</span>/usr/local/nginx --with-http_stub_status_module --with-pcre  --with-http_ssl_module
</code></pre></div><table><thead><tr><th>选项</th> <th>解释</th></tr></thead> <tbody><tr><td>--prefix=&lt;path&gt;</td> <td>Nginx安装的根目录，所有其他安装路径都要依赖于该选项</td></tr> <tr><td>--sbin- path=&lt;path&gt;</td> <td>指定Nginx二进制文件的路径</td></tr> <tr><td>--conf-path=&lt;path&gt;</td> <td>指定nginx.conf配置文件的路径</td></tr> <tr><td>--error-log- path=&lt;path&gt;</td> <td>指定错误文件的路径</td></tr> <tr><td>--user=name</td> <td>worker进程运行的用户</td></tr> <tr><td>--group=&lt;group&gt;</td> <td>worker进程运行的组</td></tr> <tr><td>--with-http_ssl_module</td> <td>使用https协议模块。默认情况下该模块没有被构建。前提是openssl与openssl-devel已安装</td></tr> <tr><td>--with-http_image_filter_module</td> <td>该模块被用作图像过滤器使用，将图像投递给客户前先进行过滤（需要libgd库）</td></tr> <tr><td>--with-http_stub_status_module</td> <td>启用这个模块会收集Nginx自身状态信息，常用来做监控</td></tr> <tr><td>--with-mail</td> <td>启用mail模块，默认没有被激活</td></tr> <tr><td>--without-http_autoindex_module</td> <td>禁用：如果一个目录没有index文件，该模块能收集文件并列出</td></tr> <tr><td>--add-module=&lt;path&gt;</td> <td>添加第三方外部模块,每次添加新的模块都要重新编译</td></tr></tbody></table> <h2 id="_7-nginx-面试题"><a href="#_7-nginx-面试题" class="header-anchor">#</a> 7. Nginx 面试题</h2> <p>恭喜你顺利来到大猿帅面试阶段，没有夹道欢迎</p> <ul><li><p>Nginx功能，你们项目中用到的Nginx？</p> <p>反向代理服务器</p> <p>实现负载均衡</p> <p>做静态资源服务器</p> <p>作为http server</p></li> <li><p>Nginx常用命令有哪写？</p> <p>启动nginx    ./sbin/nginx
停止nginx    ./sbin/nginx -s stop   ./sbin/nginx -s quit
重载配置      ./sbin/nginx -s reload(平滑重启) service nginx reload
重载指定配置文件    ./sbin/nginx -c  /usr/local/nginx/conf/nginx.conf
查看nginx版本  ./sbin/nginx -v
检查配置文件是否正确  ./sbin/nginx -t
显示帮助信息  ./sbin/nginx  -h</p></li> <li><p>Nginx常用配置？</p> <div class="language- extra-class"><pre class="language-text"><code>worker_processes 4;   #工作进程数
work_connections 65535; #每个进程的并发能力
error_log  /data/nginx/logs/error.log;  #错误日志

</code></pre></div></li> <li><p>Nginx是如何实现高并发的？</p> <p>Nginx 采用的是多进程（单线程） &amp; 多路IO复用模型,，异步，非阻塞.</p> <p>一个主进程master，多个工作进程worker，每个工作进程可以处理多个请求</p> <p>master进程主要负责收集、分发请求。每当一个请求过来时，master就拉起一个worker进程负责处理这个请求。同时master进程也负责监控woker的状态，保证高可靠性</p> <p>在nginx中的work进程中，为了应对高并发场景，采取了Reactor模型（也就是I/O多路复用，NIO）：</p> <ul><li>每一个worker进程通过I/O多路复用处理多个连接请求；</li> <li>为了减少进程切换（需要系统调用）的性能损耗，一般设置worker进程数量和CPU数量一致。</li></ul> <p>**I/O 多路复用模型：**在 I/O 多路复用模型中，最重要的系统调用函数就是 select（其他的还有epoll等），该方法的能够同时监控多个文件描述符的可读可写情况（每一个网络连接其实都对应一个文件描述符），当其中的某些文件描述符可读或者可写时，select 方法就会返回可读以及可写的文件描述符个数。</p> <p><strong>nginx work进程</strong>使用 I/O 多路复用模块同时监听多个 FD（文件描述符），当 accept、read、write 和 close 事件产生时，操作系统就会回调 FD 绑定的事件处理器，这时候work进程再去处理相应事件，而不是阻塞在某个请求连接上等待。这样就可以实现一个进程同时处理多个连接。</p></li> <li><p>nginx和apache的区别？</p> <p>轻量级，同样起web 服务，比apache 占用更少的内存及资源
抗并发，nginx 处理请求是异步非阻塞的，而apache 则是阻塞型的，在高并发下nginx 能保持低资源低消耗高性能
高度模块化的设计，编写模块相对简单
最核心的区别在于apache是同步多进程模型，一个连接对应一个进程；nginx是异步的，多个连接（万级别）可以对应一个进程</p></li> <li><p>nginx 的 upstream支持的负载均衡方式？</p></li> <li><p>轮询（默认）</p></li> <li><p>weight  ：指定权重</p></li> <li><p>ip_hash ：每个请求按访问ip的hash结果分配，这样每个访客固定访问一个后端服务器</p></li> <li><p>第三方： fair、url_hash</p></li> <li><p>Nginx常见的优化配置有哪些?</p></li></ul> <ol><li>调整worker_processes : 指Nginx要生成的worker数量,最佳实践是每个CPU运行1个工作进程</li> <li>最大化worker_connections :</li> <li>启用Gzip压缩 : 压缩文件大小，减少了客户端http的传输带宽，因此提高了页面加载速度</li> <li>为静态文件启用缓存</li> <li>禁用access_logs : 访问日志记录，它记录每个nginx请求，因此消耗了大量CPU资源，从而降低了nginx性能</li></ol> <p>参考：</p> <blockquote><p>《Nginx核心知识100讲》</p> <p>《精通Nginx》</p> <p><a href="https://juejin.im/post/5c1616186fb9a049a42ef21d" target="_blank" rel="noopener noreferrer">nginx.conf 配置文件详解<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <p>《尚硅谷Nginx》</p></blockquote></div> <footer class="page-edit" style="display:none;"><!----> <!----></footer> <!----> <!----> <!----></main> <!----></div></div></div></div><div class="global-ui"><div class="back-to-ceiling" style="right:1rem;bottom:6rem;width:2.5rem;height:2.5rem;border-radius:.25rem;line-height:2.5rem;display:none;" data-v-db14854a data-v-db14854a><svg t="1574745035067" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5404" class="icon" data-v-db14854a><path d="M526.60727968 10.90185116a27.675 27.675 0 0 0-29.21455937 0c-131.36607665 82.28402758-218.69155461 228.01873535-218.69155402 394.07834331a462.20625001 462.20625001 0 0 0 5.36959153 69.94390903c1.00431239 6.55289093-0.34802892 13.13561351-3.76865779 18.80351572-32.63518765 54.11355614-51.75690182 118.55860487-51.7569018 187.94566865a371.06718723 371.06718723 0 0 0 11.50484808 91.98906777c6.53300375 25.50556257 41.68394495 28.14064038 52.69160883 4.22606766 17.37162448-37.73630017 42.14135425-72.50938081 72.80769204-103.21549295 2.18761121 3.04276886 4.15646224 6.24463696 6.40373557 9.22774369a1871.4375 1871.4375 0 0 0 140.04691725 5.34970492 1866.36093723 1866.36093723 0 0 0 140.04691723-5.34970492c2.24727335-2.98310674 4.21612437-6.18497483 6.3937923-9.2178004 30.66633723 30.70611158 55.4360664 65.4791928 72.80769147 103.21549355 11.00766384 23.91457269 46.15860503 21.27949489 52.69160879-4.22606768a371.15156223 371.15156223 0 0 0 11.514792-91.99901164c0-69.36717486-19.13165746-133.82216804-51.75690182-187.92578088-3.42062944-5.66790279-4.76302748-12.26056868-3.76865837-18.80351632a462.20625001 462.20625001 0 0 0 5.36959269-69.943909c-0.00994388-166.08943902-87.32547796-311.81420293-218.6915546-394.09823051zM605.93803103 357.87693858a93.93749974 93.93749974 0 1 1-187.89594924 6.1e-7 93.93749974 93.93749974 0 0 1 187.89594924-6.1e-7z" p-id="5405" data-v-db14854a></path><path d="M429.50777625 765.63860547C429.50777625 803.39355007 466.44236686 1000.39046097 512.00932183 1000.39046097c45.56695499 0 82.4922232-197.00623328 82.5015456-234.7518555 0-37.75494459-36.9345906-68.35043303-82.4922232-68.34111062-45.57627738-0.00932239-82.52019037 30.59548842-82.51086798 68.34111062z" p-id="5406" data-v-db14854a></path></svg></div><!----></div></div>
    <script src="/assets/js/app.447d4224.js" defer></script><script src="/assets/js/3.9d76740c.js" defer></script><script src="/assets/js/1.c4fd7d2e.js" defer></script><script src="/assets/js/4.564edb9d.js" defer></script>
  </body>
</html>
